package com.glorystone.ins.service.impl;

import com.glorystone.ins.common.common.PageVo;
import com.glorystone.ins.dao.EaringPointMpr;
import com.glorystone.ins.dao.ProductMpr;
import com.glorystone.ins.domain.*;
import com.glorystone.ins.enums.FlowBusinessTypeEnum;
import com.glorystone.ins.enums.FlowOperateTypeEnum;
import com.glorystone.ins.enums.WorkFlowEnum;
import com.glorystone.ins.interceptor.PageList;
import com.glorystone.ins.service.AuditTaskService;
import com.glorystone.ins.service.BusinessLogService;
import com.glorystone.ins.service.CaculateService;
import com.glorystone.ins.service.ProductSvr;
import com.glorystone.ins.vo.OperateResult;
import com.glorystone.ins.vo.RebateSetVo;
import com.glorystone.ins.vo.RebateVO;
import com.glorystone.ins.vo.TaxPoint;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 项目名称：ins
 * 类名称：ProductSvrImpl
 * 类描述：产品  impl
 * 创建人：zgh
 * 创建时间：2018/3/12 14:15
 */
@Slf4j
@Service
@Transactional(readOnly = true,rollbackFor = Exception.class)
public class ProductSvrImpl implements ProductSvr{


    /**
     * 产品
     */
    @Autowired
    private ProductMpr productMpr;

    @Autowired
    private EaringPointMpr earingPointMpr;

    @Autowired
    private CaculateService caculateService;

    @Autowired
    private BusinessLogService businessLogService;

    @Autowired
    private AuditTaskService auditTaskService;

    private String TYPE_ONE="1";
    private String TYPE_ZERO="0";



    /**
     * 新建产品
     * @param product
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public OperateResult insert(Product product) {
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        OperateResult result = new OperateResult();
        if(user!=null) {
            Date date = new Date();
            String id = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            product.setPriceStatus(Product.PriceEnum.PRICE_STATUS_NO.getValue());
            product.setUseStatus(Product.UseEnum.USE_STATUS_YES.getValue());
            product.setDelFlag(Product.DelEnum.DEL_FLAG_NO.getValue());
            product.setCreateDate(date);
            product.setUpdateDate(date);
            product.setProductId(id);
            product.setCreateBy(user.getTid());
            product.setCheckNode(Product.CheckEnum.CHECK_POINT.getValue());
            product.setCheckStatus(Product.CheckStatusEnum.CHECK_STATUS_READ.getValue());
            try{
                productMpr.insertSelective(product);
                businessLogService.save(BusinessLog.BusinessTypeEnum.PRODUCT,product.getTid(),BusinessLog.ContentEnum.CREATE_PROJECT,null);
                auditTaskService.submit(WorkFlowEnum.CREATE_PRODUCT, FlowBusinessTypeEnum.PRODUCT,product.getTid(), FlowOperateTypeEnum.START);
                result.setSuccess(true);
                result.setMsg("产品新建成功！");
            }catch (Exception e){
                e.printStackTrace();
                result.setSuccess(false);
                result.setMsg("产品新建失败！");
            }
        }else{
            log.info("---------------------登录信息已过期----------------------------");
            result.setSuccess(false);
            result.setMsg("产品新建失败！登录信息已过期！");
        }
        return result;
    }
/**
     * 根据产品tid查询该上品信息
     * @param tid 产品tid
     * @return
     */
    @Override
    public Product getProjectByTid(Long tid) {
        return productMpr.selectByPrimaryKey(tid);
    }

    /**
     * 根据产品tid添加税点信息
     * @param product
     * @param remark
     * @param m
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public void updateProduct(Product product, String m, String remark) {
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        if(StringUtils.isNotEmpty(m)){
            if(TYPE_ONE.equals(m)){
                Product product1 = productMpr.selectByPrimaryKey(product.getTid());
                product1.setUseStatus(Product.UseEnum.USE_STATUS_OLD.getValue());
                product1.setPriceStatus(Product.PriceEnum.PRICE_STATUS_HISTORY.getValue());
                product1.setUpdateDate(new Date());
                product1.setUpdateBy(user.getTid());
                productMpr.updateByPrimaryKeySelective(product1);
                product1.setSeparateStatus(product.getSeparateStatus());
                product1.setModalityStatus(product.getModalityStatus());
                product1.setTid(null);
                String id = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
                product1.setPriceStatus(Product.PriceEnum.PRICE_STATUS_NO.getValue());
                product1.setUseStatus(Product.UseEnum.USE_STATUS_YES.getValue());
                product1.setCreateDate(new Date());
                product1.setCreateBy(user.getTid());
                product1.setProductId(id);
                product1.setCheckStatus(Product.CheckStatusEnum.CHECK_STATUS_READ.getValue());
                product1.setCheckNode(Product.CheckEnum.CHECK_EARING_POINT.getValue());
                productMpr.insertSelective(product1);
                businessLogService.save(BusinessLog.BusinessTypeEnum.PRODUCT,product1.getTid(),BusinessLog.ContentEnum.SET_TAX_POINT,remark);
            }else if (TYPE_ZERO.equals(m)){
                product.setUpdateDate(new Date());
                product.setUpdateBy(user.getTid());
                product.setCheckStatus(Product.CheckStatusEnum.CHECK_STATUS_READ.getValue());
                product.setCheckNode(Product.CheckEnum.CHECK_EARING_POINT.getValue());
                productMpr.updateByPrimaryKeySelective(product);
            }
        }else{
            product.setUpdateDate(new Date());
            product.setUpdateBy(user.getTid());
            product.setCheckNode(Product.CheckEnum.CHECK_AGAIN.getValue());
            product.setCheckStatus(Product.CheckStatusEnum.CHECK_STATUS_MIDDEL.getValue());
            productMpr.updateByPrimaryKeySelective(product);
        }

    }

    /**
     * 根据保险公司查询产品的账期
     * @param
     * @return
     */
    /*@Override
    public List<EaringPoint> getProductTimeByCompany(Long companyId,Integer type) {
        Product product = productMpr.getProductTimeByCompany(companyId,type);
        List<EaringPoint> list = new ArrayList<EaringPoint>();
        for (EaringPoint e:product.getEaringPointList()) {
            EaringPoint earingPoint = new EaringPoint();
            StringBuilder s = new StringBuilder("账期");
            s.append(e.getPaymentDays());
            s.append("天");
            earingPoint.setTime(s.toString());
            earingPoint.setPaymentDays(e.getPaymentDays());
            list.add(earingPoint);
        }
        return list;
    }*/

    //设置自留点位公用代码块
    private void updateEaringPiont(Long tid,String earing, String earing1,List<EaringPoint> collectionForm){
        EaringPoint earingPoint = new EaringPoint();
        earingPoint.setProductId(tid);
        earingPoint.setType(EaringPoint.TypeEnum.TYPE_STATUS_N0.getValue());
        earingPoint.setEarnings(new BigDecimal(earing));
        earingPointMpr.insertSelective(earingPoint);
        earingPoint.setType(EaringPoint.TypeEnum.TYPE_STATUS_YES.getValue());
        earingPoint.setEarnings(new BigDecimal(earing1));
        earingPointMpr.insertSelective(earingPoint);
        for (EaringPoint e: collectionForm) {
            if(e.getEarnings()!=null&&e.getPaymentDays()!=null){
                e.setProductId(tid);
                e.setType(EaringPoint.TypeEnum.TYPE_STATUS_ALL.getValue());
                earingPointMpr.insertSelective(e);
            }
        }
    }
    /**
     * 设置自留点位
     * @param earing
     * @param earing1
     * @param tid
     * @param collectionForm
     * @param m
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public void setEaringPoint(String earing, String earing1, String tid, List<EaringPoint> collectionForm, String m,String remark) {
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        if(StringUtils.isNotEmpty(m)){
            if(TYPE_ONE.equals(m)){
                Product product1 = productMpr.selectByPrimaryKey(Long.parseLong(tid));
                product1.setUseStatus(Product.UseEnum.USE_STATUS_OLD.getValue());
                product1.setPriceStatus(Product.PriceEnum.PRICE_STATUS_HISTORY.getValue());
                product1.setUpdateDate(new Date());
                product1.setUpdateBy(user.getTid());
                productMpr.updateByPrimaryKeySelective(product1);
                String id = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
                product1.setTid(null);
                product1.setPriceStatus(Product.PriceEnum.PRICE_STATUS_NO.getValue());
                product1.setUseStatus(Product.UseEnum.USE_STATUS_YES.getValue());
                product1.setCreateDate(new Date());
                product1.setCreateBy(user.getTid());
                product1.setProductId(id);
                product1.setCheckNode(Product.CheckEnum.CHECK_FIRST.getValue());
                product1.setCheckStatus(Product.CheckStatusEnum.CHECK_STATUS_READ.getValue());
                productMpr.insertSelective(product1);
                businessLogService.save(BusinessLog.BusinessTypeEnum.PRODUCT,product1.getTid(),BusinessLog.ContentEnum.SET_EARNING_POINT,remark);
                Long tid1 = product1.getTid();
                updateEaringPiont(tid1,earing,earing1,collectionForm);

            }else {
                updateEaringPiont(Long.parseLong(tid),earing,earing1,collectionForm);
                Product product = new Product();
                product.setTid(Long.parseLong(tid));
                product.setUpdateDate(new Date());
                product.setUpdateBy(user.getTid());
                product.setCheckNode(Product.CheckEnum.CHECK_FIRST.getValue());
                productMpr.updateByPrimaryKeySelective(product);
            }
        }
    }

    /**
     * 查询产品的详细信息
     * @param tid
     * @return
     */
    @Override
    public Product getProductByTid(Long tid) {
        return productMpr.getProductByTid(tid);
    }

    /**
     * 改变产品状态
     * @param status
     * @param tid
     * @return
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public void updateProductStatus(Integer status, Long tid) {
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        Product product = new Product();
        product.setTid(tid);
        product.setUseStatus(status);
        product.setUpdateDate(new Date());
        product.setUpdateBy(user.getTid());
        productMpr.updateByPrimaryKeySelective(product);
    }

    /**
     * 查询所有产品
     * @return
     * @param t
     */
    @Override
    public PageList<Product> findList(Integer t, PageVo vo) {
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        Long tid =null;
        if(user!=null){
             tid = user.getTid();
        }else {
            log.info("--------------------登录信息已过期----------------------------");
        }
        return productMpr.selectAll(tid,t,vo,vo.getPageable());
    }

    /**
     * 把产品变为已定价状态
     * @param product
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public void updateProducts(Product product) {
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        product.setUpdateDate(new Date());
        product.setUpdateBy(user.getTid());
        product.setCheckNode(Product.CheckEnum.CHECK_SUCCESS.getValue());
        product.setPriceStatus(Product.PriceEnum.PRICE_STATUS_YES.getValue());
        productMpr.updateByPrimaryKeySelective(product);
    }

    /**
     * 检查该产品是否已被禁用
     * @param companyId
     * @return
     */
    @Override
    public List<Product> selectProductStatus(Long companyId) {
        List<Product> list = productMpr.getProductByCompanyIdAndType(companyId);
        return list;
    }

    /**
     * 驳回
     * @param product
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public void rejectProduct(Product product) {
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        Product product1 = productMpr.selectByPrimaryKey(product.getTid());
        //新建一个产品
        Product product2 = new Product();
        String id = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        product2.setCreateDate(new Date());
        product2.setDelFlag(Product.DelEnum.DEL_FLAG_NO.getValue());
        product2.setCompanyId(product1.getCompanyId());
        product2.setCompany(product1.getCompany());
        product2.setContractTime(product1.getContractTime());
        product2.setProductId(id);
        product2.setUserId(product1.getUserId());
        product2.setUserName(product1.getUserName());
        product2.setUseStatus(product1.getUseStatus());
        product2.setPriceStatus(product1.getPriceStatus());
        product2.setType(product1.getType());
        product2.setCreateBy(user.getTid());
        product2.setUpdateDate(new Date());
        product2.setUpdateBy(user.getTid());
        product2.setCheckNode(Product.CheckEnum.CHECK_POINT.getValue());
        product2.setCheckStatus(Product.CheckStatusEnum.CHECK_STATUS_REJECT.getValue());
        productMpr.insertSelective(product2);
        auditTaskService.submit(WorkFlowEnum.CREATE_PRODUCT, FlowBusinessTypeEnum.PRODUCT,product2.getTid(), FlowOperateTypeEnum.START);
        //新建产品的操作记录
        businessLogService.save(BusinessLog.BusinessTypeEnum.PRODUCT,product2.getTid(),BusinessLog.ContentEnum.CREATE_PROJECT,product2.getOpinion());
        //将原来的产品修改为历史
        product1.setUpdateDate(new Date());
        product1.setUpdateBy(user.getTid());
        product1.setPriceStatus(Product.PriceEnum.PRICE_STATUS_HISTORY.getValue());
        product1.setUseStatus(Product.UseEnum.USE_STATUS_OLD.getValue());
        product1.setCheckNode(Product.CheckEnum.CHECK_POINT.getValue());
        product1.setCheckStatus(Product.CheckStatusEnum.CHECK_STATUS_REJECT.getValue());
        productMpr.updateByPrimaryKey(product1);

        /*earingPointMpr.deleteByProjectId(product.getTid());*/
    }

    /**
     * 查询所有有可用产品的保险公司
     * @return
     */
    @Override
    public List<Insurer> getCompany() {
        return productMpr.getCompany();
    }

    /**
     * 删除
     * @param tid
     * @return
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public void deleteById(Long tid) {
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        Product product = new Product();
        product.setTid(tid);
        product.setDelFlag(Product.DelEnum.DEL_FLAG_YES.getValue());
        product.setUpdateDate(new Date());
        product.setUpdateBy(user.getTid());
        productMpr.updateByPrimaryKeySelective(product);
    }

    /**
     * 校验产品唯一
     * @param companyId
     * @param type
     * @return
     */
    @Override
    public Integer checkProduct(Long companyId, Integer type) {
        Integer count = productMpr.selectProductBycompanyIdAndType(companyId,type);
        return count;
    }

    /**
     * 计算渠道税点和税后保费
     * @return
     */
    private RebateSetVo calculation(Product product,RebateSetVo rebateSetVo){
        OperateResult operateResult = new OperateResult();
        RebateVO rebateVO = new RebateVO();
        //价税分离税点
        if(Product.SeparateStatusEnum.SEPARATESTATUS_YES.getValue().equals(product.getSeparateStatus())){
            rebateVO.setSeparatePoint(TaxPoint.SEPARATEPOINT_YES);
        }else{
            rebateVO.setSeparatePoint(TaxPoint.SEPARATEPOINT_NO);
        }
        //补点开票类型
        rebateVO.setType(product.getModalityStatus());
        //跟单点位
        rebateVO.setFollowTicketPoint(rebateSetVo.getFollowTicketPoint());
        //补点点位
        rebateVO.setSupplementPoint(rebateSetVo.getSupplementPoint());
        //自留点位
        for (EaringPoint e:product.getEaringPointList()) {
            rebateVO.setSelfPoint(e.getEarnings());
        }
        //开票税点
        if(RebateSetVo.PaySubjectEnum.DRAGON.getValue().equals(rebateSetVo.getPaySubject())){
            rebateVO.setTicketTaxPoint(TaxPoint.TICKETTAXPOINT_HL);
        }else{
            rebateVO.setTicketTaxPoint(TaxPoint.TICKETTAXPOINT_OTHER);
        }
        //开票比例
        if(RebateSetVo.PaySubjectEnum.HUANYU.getValue().equals(rebateSetVo.getPaySubject())){
            rebateVO.setTicketRate(TaxPoint.TICKETRATE_HUANYU);
        }else if(RebateSetVo.PaySubjectEnum.QINGDAO.getValue().equals(rebateSetVo.getPaySubject())){
            rebateVO.setTicketRate(TaxPoint.TICKETRATE_QINGDAO);
        }else if(RebateSetVo.PaySubjectEnum.YUHUAN.getValue().equals(rebateSetVo.getPaySubject())){
            rebateVO.setTicketRate(TaxPoint.TICKETRATE_YUHUAN);
        }else{
            rebateVO.setTicketRate(TaxPoint.TICKETRATE_HANLONG);
        }
        rebateVO.setPercent(true);
        log.info("----------------------------计算渠道返点----------------------------------");
        BigDecimal channelRebate = caculateService.calcRebateRate(rebateVO);
        log.info("----------------------------计算税后保费-------------------------------------");
        BigDecimal texPremium = caculateService.calcFeeAfterTax(rebateSetVo.getAllPremium(), rebateVO.getSeparatePoint(), false);
        RebateSetVo rebateSetVo1 = new RebateSetVo();
        rebateSetVo1.setChannelRebate(channelRebate);
        rebateSetVo1.setTexPremium(texPremium);
        rebateSetVo1.setProductId(product.getTid());

        return rebateSetVo1;
    }
    /**
     * 获取渠道返点和税后保费
     * @param rebateSetVo
     * @return
     */
    @Override
    public OperateResult getRebateAndMoney(RebateSetVo rebateSetVo) throws ParseException {
        OperateResult operateResult = OperateResult.createMsg(false,"计算渠道返点开始");
        log.info("--------------入参rebateSetVo:"+rebateSetVo+"--------------------------------");
        Product product = productMpr.getProductMessage(rebateSetVo);
        Product product1 = null;
        if(product==null){
            log.info("--------------该产品不存在--------------------------------");
            operateResult.setMsg("该产品不存在");
            rebateSetVo.setStatus(1);
        }else if(Product.UseEnum.USE_STATUS_OLD.getValue().equals(product.getUseStatus())||Product.UseEnum.USE_STATUS_OVERTIME.getValue().equals(product.getUseStatus())){
            log.info("--------------该产品已修改或已经过期无法继续下单--------------------------------");
            product1 = productMpr.getProduct(product.getCompanyId(),product.getType());
            if(product1 == null){
                log.info("--------------该产品不可用--------------------------------");
                operateResult.setMsg("该产品不可用");
                rebateSetVo.setStatus(1);
            }else{
                log.info("--------------该产品可以正常使用--------------------------------");
                //RebateSetVo rebateSetVo1 = calculation(product1, rebateSetVo);
                //operateResult.setResult(rebateSetVo1);
                rebateSetVo.setStatus(2);
                operateResult.setMsg("该产品已变更");
            }
        }else if(Product.UseEnum.USE_STATUS_NO.getValue().equals(product.getUseStatus())){
            log.info("--------------该产品不可用--------------------------------");
            operateResult.setMsg("该产品不可用");
            rebateSetVo.setStatus(1);
        }else if(Product.PriceEnum.PRICE_STATUS_YES.getValue().equals(product.getPriceStatus())&&Product.UseEnum.USE_STATUS_YES.getValue().equals(product.getUseStatus())){
            log.info("--------------该产品可以正常使用--------------------------------");
            rebateSetVo = calculation(product, rebateSetVo);
            operateResult.setMsg("该产品可以正常使用");
            operateResult.setSuccess(true);
            rebateSetVo.setStatus(0);
        }else{
            log.info("--------------该产品不可用--------------------------------");
            operateResult.setMsg("该产品不可用");
            rebateSetVo.setStatus(1);
        }
        operateResult.setResult(rebateSetVo);
        return operateResult;
    }

    /**
     * 支付时检查产品的状态
     * @param productId
     * @return
     */
    @Override
    public OperateResult checkProductMessage(Long productId) {
        OperateResult operateResult = new OperateResult();
        log.info("--------------入参产品id:"+productId+"--------------------------------");
        RebateSetVo rebateSetVo = new RebateSetVo();
        rebateSetVo.setProductId(productId);
        Product product = productMpr.getProductMessageByProductId(rebateSetVo);
        rebateSetVo.setProductId(null);
        Product product1 = null;
        if(product==null){
            log.info("--------------该产品不可用--------------------------------");
            operateResult.setMsg("该产品不存在");
            rebateSetVo.setStatus(1);
        }else if(Product.UseEnum.USE_STATUS_OLD.getValue().equals(product.getUseStatus())||Product.UseEnum.USE_STATUS_OVERTIME.getValue().equals(product.getUseStatus())){
            log.info("--------------该产品已修改或已经过期无法继续下单--------------------------------");
            rebateSetVo.setProduct_update_date(product.getUpdateDate());
            product1 = productMpr.getProduct(product.getCompanyId(),product.getType());
            if(product1 == null){
                log.info("--------------该产品不可用--------------------------------");
                operateResult.setMsg("该产品不可用");
                rebateSetVo.setStatus(1);
            }else{
                log.info("--------------该产品可以正常使用--------------------------------");
                operateResult.setMsg("新产品可以正常使用");
                rebateSetVo.setStatus(2);
                List<EaringPoint> list = earingPointMpr.getEaringList(product1.getTid());
                rebateSetVo.setProductId(product1.getTid());
                rebateSetVo.setList(list);
            }
        }else if(Product.UseEnum.USE_STATUS_NO.getValue().equals(product.getUseStatus())){
            log.info("--------------该产品不可用--------------------------------");
            operateResult.setMsg("该产品不可用");
            rebateSetVo.setStatus(1);
            rebateSetVo.setProduct_update_date(product.getUpdateDate());
        }else if(Product.PriceEnum.PRICE_STATUS_YES.getValue().equals(product.getPriceStatus())&&Product.UseEnum.USE_STATUS_YES.getValue().equals(product.getUseStatus())){
            log.info("--------------该产品可以正常使用--------------------------------");
            rebateSetVo.setStatus(0);
        }else{
            log.info("--------------该产品不可用--------------------------------");
            operateResult.setMsg("该产品不可用");
            rebateSetVo.setStatus(1);
            rebateSetVo.setProduct_update_date(product.getUpdateDate());
        }
        operateResult.setSuccess(true);
        operateResult.setResult(rebateSetVo);
        return operateResult;
    }

    /**
     * 查询所有已定价产品列表
     * @return
     */
    @Override
    public List<Product> findAllPriceList() {
        return productMpr.findAllPriceList();
    }

    /**
     * 产品过期修改状态
     * @param product
     */
    @Override
    public int updateProductToOverTime(Product product) {
        int i = productMpr.updateByPrimaryKeySelective(product);
        return i;
    }

    /**
     * 查看驳回产品详情
     * @param tid
     * @return
     */
    @Override
    public Product getRejectProductByTid(Long tid) {
        return productMpr.getRejectProductByTid(tid);
    }


}
